﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace mlnx_os_sysdump_analyzer
{
    class IssDump : IDisposable
    {
        private DataTable issPortDBListTable = null;
        private DataTable port_indexes_htListTable = null;
        private string issdLAGCache = "";
        private DataTable interfaces_ht_ListTable = null;
        private DataTable issdPFCCacheListTable = null;
        private string iisdETSCache = "";
        private DataTable vlanMembersListTable = null;
        private bool KEEP_RUNNING; 
        private string OUTPUT_DIR_PATH;
        //
        //----------------------------------------------------
        //
        public IssDump(ref bool KEEP_RUNNING, ref string OUTPUT_DIR_PATH)
        {
            this.KEEP_RUNNING = KEEP_RUNNING;   
            this.OUTPUT_DIR_PATH = OUTPUT_DIR_PATH;
            // create a DataTable
            issPortDBListTable = new DataTable();
            // add columns
            issPortDBListTable.Columns.Add("gPortMapping", typeof(string));
            issPortDBListTable.Columns.Add("Value", typeof(int));

            // create a DataTable
            port_indexes_htListTable = new DataTable();
            // add columns
            port_indexes_htListTable.Columns.Add("Interface index", typeof(long));
            port_indexes_htListTable.Columns.Add("Logical index", typeof(long));
            port_indexes_htListTable.Columns.Add("Slot", typeof(long));
            port_indexes_htListTable.Columns.Add("Port", typeof(long));
            port_indexes_htListTable.Columns.Add("Switch name", typeof(string));
            port_indexes_htListTable.Columns.Add("Interface name", typeof(string));
            port_indexes_htListTable.Columns.Add("Original Interface name", typeof(string));
            port_indexes_htListTable.Columns.Add("Speed HW CAP", typeof(string));
            port_indexes_htListTable.Columns.Add("Speed SW LIMIT", typeof(string));

            // create a DataTable
            interfaces_ht_ListTable = new DataTable();
            // add columns
            interfaces_ht_ListTable.Columns.Add("Interface index", typeof(long));
            interfaces_ht_ListTable.Columns.Add("Slot", typeof(long));
            interfaces_ht_ListTable.Columns.Add("Port", typeof(long));
            interfaces_ht_ListTable.Columns.Add("Switch name", typeof(string));
            interfaces_ht_ListTable.Columns.Add("Shutdown status", typeof(long));
            interfaces_ht_ListTable.Columns.Add("lacp rate fast", typeof(long));
            interfaces_ht_ListTable.Columns.Add("lacp priortiy", typeof(long));
            interfaces_ht_ListTable.Columns.Add("mtu value", typeof(long));
            interfaces_ht_ListTable.Columns.Add("fc send", typeof(string));
            interfaces_ht_ListTable.Columns.Add("fc receive ", typeof(string));
            interfaces_ht_ListTable.Columns.Add("Speed", typeof(long));
            interfaces_ht_ListTable.Columns.Add("Load balance", typeof(string));
            interfaces_ht_ListTable.Columns.Add("Channel group", typeof(long));
            interfaces_ht_ListTable.Columns.Add("Low level channel group", typeof(long));
            interfaces_ht_ListTable.Columns.Add("Channel group mode", typeof(string));

            // create a DataTable
            issdPFCCacheListTable = new DataTable();
            // add columns
            issdPFCCacheListTable.Columns.Add("interface", typeof(long));
            issdPFCCacheListTable.Columns.Add("mode", typeof(int));
            issdPFCCacheListTable.Columns.Add("advertise", typeof(int));

            // create a DataTable
            vlanMembersListTable = new DataTable();
            // add columns
            vlanMembersListTable.Columns.Add("Interface index", typeof(long));
            vlanMembersListTable.Columns.Add("Members", typeof(string));
        }
        //
        //----------------------------------------------------
        //
        public DataTable getIssPortDBList()
        {
            return issPortDBListTable;
        }
        //
        //----------------------------------------------------
        //
        public DataTable getPortIndexesHtList()
        {
            return port_indexes_htListTable;
        }
        //
        //----------------------------------------------------
        //
        public string getIssdLAGCache()
        {
            return issdLAGCache;
        }
        //
        //----------------------------------------------------
        //
        public string getIisdETSCache()
        {
            return iisdETSCache;
        }
        //
        //----------------------------------------------------
        //
        public DataTable getinterfaces_ht_List()
        {
            return interfaces_ht_ListTable;
        }
        //
        //----------------------------------------------------
        //
        public DataTable getIssdPFCCacheList()
        {
            return issdPFCCacheListTable;
        }
         //
        //----------------------------------------------------
        //
        public DataTable getVlanMembersList()
        {
            return vlanMembersListTable;
        }
        //
        //----------------------------------------------------
        //
        public void scanInfo()
        {
            string path = Methods.FindFileRec(OUTPUT_DIR_PATH, "issdump");
            if (path != null)
            {
                scanFile(path);
            }
        }
        //
        //----------------------------------------------------
        //
        public void scanFile(string srcFilePath)
        {
            if (srcFilePath == null)
                return;
            StreamReader sr = new StreamReader(srcFilePath);
            string line = "";
            try
            {
                // #################################################
                // ======printing ISS port DB====
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    if (sr.ReadLine().Contains("======printing ISS port DB===="))
                    {
                        break;
                    }
                }
                sr.ReadLine();
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    // read line
                    line = sr.ReadLine();
                    try
                    {
                        if (line.Contains("=====PRINTING port_indexes_ht===="))
                        {
                            break;
                        }
                        else
                        {
                            string[] tmpArr1 = Regex.Split(line, @"\[");
                            tmpArr1 = Regex.Split(tmpArr1[1], @"\]");
                            string[] tmpArr2 = Regex.Split(line, @"=");
                            tmpArr2[1] = Regex.Replace(tmpArr2[1], "=", "");
                            // add it to the list 
                            Item tmp = new Item(tmpArr1[0], tmpArr2[1]);
                            issPortDBListTable.Rows.Add(tmp.itemName, Int32.Parse(tmp.content));
                        }
                    }//try
                    catch { }
                }

                // #################################################
                // =====PRINTING port_indexes_ht====
                sr.ReadLine();
                portIndexesHtFields tmpPortIndexesHtField = null;
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    // read line
                    line = sr.ReadLine();
                    try
                    {
                        if (line.Contains("last dump took")) // end of =====PRINTING port_indexes_ht====
                        {
                            break;
                        }
                        else
                        {
                            if (line.Contains(" "))
                            {
                                tmpPortIndexesHtField = new portIndexesHtFields();
                                //ifindex        
                                tmpPortIndexesHtField.ifindex = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(line), " ")[1]);
                                //logicalindex   
                                tmpPortIndexesHtField.logicalindex = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                                //slot           
                                tmpPortIndexesHtField.slot = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                                //port           
                                tmpPortIndexesHtField.port = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                                //switchname     
                                tmpPortIndexesHtField.switchname = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                                //ifname         
                                tmpPortIndexesHtField.ifname = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                                //originalifname 
                                tmpPortIndexesHtField.originalifname = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                                //speed_hw_cap   
                                tmpPortIndexesHtField.speed_hw_cap = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                                //speed_sw_limit 
                                tmpPortIndexesHtField.speed_sw_limit = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                                // add it to the list 
                                port_indexes_htListTable.Rows.Add(tmpPortIndexesHtField.ifindex,
                                    tmpPortIndexesHtField.logicalindex,
                                    tmpPortIndexesHtField.slot,
                                    tmpPortIndexesHtField.port,
                                    tmpPortIndexesHtField.switchname,
                                    tmpPortIndexesHtField.ifname,
                                    tmpPortIndexesHtField.originalifname,
                                    tmpPortIndexesHtField.speed_hw_cap,
                                    tmpPortIndexesHtField.speed_sw_limit);
                                sr.ReadLine();
                            }
                        }
                    }//try
                    catch { }
                }
                // #################################################
                // =====ISSD LAG Cache dump start:=====
                sr.ReadLine();
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    // read line
                    line = sr.ReadLine();
                    try
                    {
                        if (line.Contains("=====ISSD LAG Cache dump end====="))
                        {
                            break;
                        }
                        else
                        {
                            issdLAGCache += line + "\r\n";
                        }
                    }//try
                    catch { }
                }

                // #################################################
                // =====PRINTING interfaces_ht====
                sr.ReadLine();sr.ReadLine();sr.ReadLine();
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    // read line
                    line = sr.ReadLine();
                    try
                    {
                        if (line.Contains("last dump took"))
                        {
                            break;
                        }
                        else
                        {
                            InterfacesHtFields tmpIf = new InterfacesHtFields();
                            //ifindex
                            tmpIf.ifindex = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(line), " ")[1]);
                            //slot                     
                            tmpIf.slot = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //port                     
                            tmpIf.port = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //switch_name              
                            tmpIf.switch_name = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                            //shutdown_status          
                            tmpIf.shutdown_status = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //lacp_rate_fast           
                            tmpIf.lacp_rate_fast = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //lacp_priortiy            
                            tmpIf.lacp_priortiy = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //mtu_value                
                            tmpIf.mtu_value = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //fc_send                  
                            tmpIf.fc_send = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                            //fc_receive               
                            tmpIf.fc_receive = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                            //speed                    
                            tmpIf.speed = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //load_balance             
                            tmpIf.load_balance = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                            //channel_group            
                            tmpIf.channel_group = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //low_level_channel_group  
                            tmpIf.low_level_channel_group = long.Parse(Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1]);
                            //channel_group_mode       
                            tmpIf.channel_group_mode = Regex.Split(Methods.RemoveExtraSpaces(sr.ReadLine()), " ")[1];
                            interfaces_ht_ListTable.Rows.Add(tmpIf.ifindex,
                                tmpIf.slot,
                                tmpIf.port,
                                tmpIf.switch_name,
                                tmpIf.shutdown_status,
                                tmpIf.lacp_rate_fast,
                                tmpIf.lacp_priortiy,
                                tmpIf.mtu_value,
                                tmpIf.fc_send,
                                tmpIf.fc_receive,
                                tmpIf.speed,
                                tmpIf.load_balance,
                                tmpIf.channel_group,
                                tmpIf.low_level_channel_group,
                                tmpIf.channel_group_mode);

                            sr.ReadLine();
                        }
                    }//try
                    catch { }
                }
                // #################################################
                // =====ISSD PFC Cache dump start:=====
                sr.ReadLine();sr.ReadLine();sr.ReadLine();
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    // read line
                    line = sr.ReadLine();
                    try
                    {
                        if (line.Contains("=====ISSD PFC Cache dump end====="))
                        {
                            break;
                        }
                        else
                        {
                            if (!line.Equals("") && line.Contains("advertise"))
                        	{
	                            IssdPFCCacheFields tmpPfc = new IssdPFCCacheFields();
	                            line = Methods.RemoveExtraSpaces(line);
	                            string []tmpsArr = Regex.Split(line, " ");
	                            if (line.Contains(" :"))
	                            {
	                                tmpPfc.interfaceN = long.Parse(Regex.Replace(tmpsArr[1], ":", ""));
	                                tmpPfc.mode = Int32.Parse(Regex.Replace(Regex.Split(tmpsArr[3], "=")[1], "=", ""));
	                                tmpPfc.advertise = Int32.Parse(Regex.Replace(Regex.Split(tmpsArr[4], "=")[1], "=", ""));
	                            }
	                            else
	                            {
	                                tmpPfc.interfaceN = long.Parse(Regex.Replace(tmpsArr[1], ":", "")); 
	                                tmpPfc.mode = Int32.Parse(Regex.Replace(Regex.Split(tmpsArr[2], "=")[1], "=", ""));
	                                tmpPfc.advertise = Int32.Parse(Regex.Replace(Regex.Split(tmpsArr[3], "=")[1], "=", ""));
	                            }
	                            issdPFCCacheListTable.Rows.Add(tmpPfc.interfaceN, tmpPfc.mode, tmpPfc.advertise);
                        	}
                        }
                    }//try
                    catch { }
                }

                // #################################################
                // =====ISSD ETS Cache dump start:=====
                sr.ReadLine(); sr.ReadLine();
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    // read line
                    line = sr.ReadLine();
                    try
                    {
                        if (line.Contains("=====ISSD ETS Cache dump end====="))
                        {
                            break;
                        }
                        else
                        {
                            iisdETSCache += line + "\r\n";
                        }
                    }//try
                    catch { }
                }

                // #################################################
                // =====PRINTING VLAN MEMBERS FOR EACH PORT FROM ISS DB====
                sr.ReadLine(); sr.ReadLine();sr.ReadLine();
               // vlanMembersList
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    // read line
                    line = sr.ReadLine();
                    try
                    {
                        if (line.Contains("last dump took"))
                        {
                            break;
                        }
                        else
                        {
                            Item tmptm1 = new Item();
                            line = Methods.RemoveExtraSpaces(line);
                            if (line.Contains(" "))
                            {
                                tmptm1.itemName = Regex.Split(line, " ")[1];
                                tmptm1.content = sr.ReadLine();
                                vlanMembersListTable.Rows.Add(long.Parse(tmptm1.itemName), tmptm1.content);
                                sr.ReadLine();
                            }
                        }
                    }//try
                    catch { }
                }
            }//try
            catch { }
            sr.Dispose();
        }
        //
        //----------------------------------------------------
        //

        public void Dispose()
        {
            if (issPortDBListTable != null)
            {
                issPortDBListTable.Dispose();
            }
           
            if (port_indexes_htListTable != null)
            {
                port_indexes_htListTable.Dispose();
            }

            if (interfaces_ht_ListTable != null)
            {
                interfaces_ht_ListTable.Dispose();
            }

            if (issdPFCCacheListTable != null)
            {
                issdPFCCacheListTable.Dispose();
            }

            if (vlanMembersListTable != null)
            {
                vlanMembersListTable.Dispose();
            }
        }
    }
}
